﻿#region Copyright Notice
// 
// 
//  
//  Copyright (c) 2009-2011 Anindya Chatterjee
//  
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//  
//      http://www.apache.org/licenses/LICENSE-2.0
//  
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// 
// 
#endregion
using System;
using System.Collections.Generic;
using System.Reflection;
using AbstractClass.NPerf.Framework;

namespace AbstractClass.NPerf
{
    /// <summary>
    /// Represents a performance test unit.
    /// </summary>
    public class TestUnit
    {
        /// <summary>
        /// The number of concurrent threads on which the test method will run. 
        /// </summary>
        public int Threads;

        /// <summary>
        /// The time unit of the test.
        /// </summary>
        public TimePeriod TimeUnit;

        /// <summary>
        /// Initializes a new instance of the <see cref="TestUnit"/> class.
        /// </summary>
        public TestUnit()
        {
            Name = null;
            IsIgnored = false;
            IgnoredMessage = null;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TestUnit"/> class.
        /// </summary>
        /// <param name="mi">The <see cref="MethodInfo"/> object of the test method.</param>
        public TestUnit(MethodInfo mi) : this(null, mi)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TestUnit"/> class.
        /// </summary>
        /// <param name="type">The type containing the test method.</param>
        /// <param name="mi">The <see cref="MethodInfo"/> object of the test method.</param>
        public TestUnit(Type type, MethodInfo mi)
        {
            if (mi == null)
                throw new ArgumentNullException("mi");

            Name = mi.Name;

            IsIgnored = mi.HasCustomAttribute(typeof (PerfTestIgnoreAttribute));
            if (IsIgnored)
            {
                var attr = (PerfTestIgnoreAttribute)
                           mi.GetFirstCustomAttribute(typeof (PerfTestIgnoreAttribute));
                IgnoredMessage = attr.Message;
            }
            else
                IgnoredMessage = null;

            TestType = type;
            TestMethod = mi;
        }

        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        /// <value>The name.</value>
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is ignored.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is ignored; otherwise, <c>false</c>.
        /// </value>
        public bool IsIgnored { get; set; }

        /// <summary>
        /// Gets or sets the ignored message.
        /// </summary>
        /// <value>The ignored message.</value>
        public string IgnoredMessage { get; set; }

        /// <summary>
        /// Gets or sets the warning message.
        /// </summary>
        /// <value>The warning message.</value>
        public string WarningMessage { get; set; }

        /// <summary>
        /// Gets or sets the test method.
        /// </summary>
        /// <value>The test method.</value>
        public MethodInfo TestMethod { get; set; }

        /// <summary>
        /// Gets or sets the type of the test.
        /// </summary>
        /// <value>The type of the test.</value>
        public Type TestType { get; set; }

        /// <summary>
        /// Gets or sets the fixture.
        /// </summary>
        /// <value>The fixture.</value>
        public TestFixture Fixture { get; set; }

        /// <summary>
        /// Gets or sets the test types.
        /// </summary>
        /// <value>The test types.</value>
        public List<TestType> TestTypes { get; set; }

        /// <summary>
        /// Gets or sets the test iteration.
        /// </summary>
        /// <value>The test iteration.</value>
        public int TestIteration { get; set; }

        /// <summary>
        /// Gets or sets the test result.
        /// </summary>
        /// <value>The test result.</value>
        public TestResult TestResult { get; set; }

        /// <summary>
        /// Gets or sets the test suite.
        /// </summary>
        /// <value>The test suite.</value>
        public TestSuite TestSuite { get; set; }

        /// <summary>
        /// Gets or sets the test description.
        /// </summary>
        /// <value>The test description.</value>
        public string TestDescription { get; set; }


        /// <summary>
        /// Gets or sets the name of the category of the performance counter.
        /// </summary>
        /// <value>The name of the category.</value>
        public string CategoryName { get; set; }

        /// <summary>
        /// Gets or sets the name of the performance counter.
        /// </summary>
        /// <value>The name of the counter.</value>
        public string CounterName { get; set; }

        /// <summary>
        /// Gets or sets the name of the instance of the performance counter.
        /// </summary>
        /// <value>The name of the instance.</value>
        public string InstanceName { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is a generic performance counter test unit.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is a generic performance counter test unit; otherwise, <c>false</c>.
        /// </value>
        public bool IsGenericCounterUnit { get; set; }
    }
}